package com.yuxl.admin.common.security.service;

import com.yuxl.admin.manager.auth.core.repository.AuthRoleRepository;
import com.yuxl.admin.manager.auth.core.repository.AuthUserRepository;
import com.yuxl.admin.manager.auth.core.repository.AuthUserRoleRepository;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.ReactiveUserDetailsService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
@Slf4j
@Service
public class CustomUserDetailsService implements ReactiveUserDetailsService {

	// 创建日志记录器
	private final AuthUserRepository authUserRepository;
	private final AuthUserRoleRepository authUserRoleRepository;
	private final AuthRoleRepository authRoleRepository;

	// 构造函数，注入AuthUserRepository
	public CustomUserDetailsService(AuthUserRepository authUserRepository,
                                    AuthUserRoleRepository authUserRoleRepository,
                                    AuthRoleRepository authRoleRepository) {
		this.authUserRepository = authUserRepository;
		this.authUserRoleRepository = authUserRoleRepository;
		this.authRoleRepository = authRoleRepository;
	}

	@Override
	public Mono<UserDetails> findByUsername(String username) {
		// 记录尝试查找用户的日志
		log.debug("尝试查找用户: {}", username);
		return authUserRepository.findByUsername(username)
				.flatMap(user -> {
					// 如果找到用户，记录日志并创建UserDetails对象
					log.debug("找到用户: {}", username);
					return authUserRoleRepository.findByUserId(user.getId())
							.flatMap(userRole -> authRoleRepository.findById(userRole.getRoleId()))
							.map(role -> new SimpleGrantedAuthority("ROLE_" + role.getMark()))
							.collectList()
							.map(authorities -> User.withUsername(user.getUsername())
									.password(user.getPassword())
									.authorities(authorities)
									.build());
				})
				.switchIfEmpty(Mono.defer(() -> {
					// 如果没有找到用户，记录警告日志
					log.warn("未找到用户: {}", username);
					return Mono.empty();
				}))
				.doOnError(error -> log.error("查找用户时发生错误: {}", username, error));
	}

}